/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
// pjpghwconv.hpp - JPEG decoder using Hardware accelerator on dm355.
//
// Author: Umesh Gawande
//
// Copyright (c) 1997-2002 Swell Software
//              All Rights Reserved.
//
// Unauthorized redistribution of this source code, in whole or part,
// without the express written permission of Swell Software
// is strictly prohibited.
//
// Notes:
//
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
#ifdef PEG_JPG_HW_CONVERT

#ifndef _PEGJPGHWCONVERT_
#define _PEGJPGHWCONVERT_

#include "pjpgconv.hpp"

#include <xdc/std.h>
#include <ti/sdo/ce/CERuntime.h>
#include <ti/sdo/ce/trace/gt.h>
#include <ti/sdo/ce/Engine.h>
#include <ti/sdo/ce/osal/Memory.h>
#include <ti/sdo/ce/image1/imgdec1.h>
#include <ti/sdo/ce/trace/gt.h>

/* IPIPE related files */
#include <fcntl.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <asm-arm/arch/dm355_ipipe.h>
#include <asm-arm/arch/dm355_ipipe_hw.h>

//Added for new features of JPEG DECODER (rotation & resize)
#include <ti/sdo/codecs/jpegdec/dm355/ijpegdec.h>
#include <ti/xdais/dm/iimgdec1.h>

//For enabling DEBUG PRINTF's
#ifdef ENABLE_DBG_PRINTF
#define DEBUG_PRINTF(fmt, args...)     printf(fmt,args)
#else
#define DEBUG_PRINTF(fmt, args...)
#endif

#define MOD_NAME "jpegdec" //Module name for JPEG decoder H/W accelerator

/* for simplicity, define the max width/height of images to be decoded */
#define MAXWIDTH      5760 //960
#define MAXHEIGHT     3840 //960

#define BUFALIGN Memory_DEFAULTALIGNMENT

/* return values for functions*/
#define HW_DECODE_SUCCESS 1
#define HW_DECODE_FAIL  0

#define DISPLAY_WIDTH   720
#define DISPLAY_HEIGHT  480

#define SCALEBITS    16    /* speediest right-shift on some machines */
#define ONE_HALF    ((PEGLONG) 1 << (SCALEBITS-1))

#ifdef PEG_FP_GRAPHICS
#define FIX(x)        ((PEGLONG) ((x) * (1L<<SCALEBITS) + 0.5))
#else
#define FIX(x)        ((PEGLONG) ((x) * (1L<<SCALEBITS)))
#endif

//Structure for storing JPEG decoded image info as well as data
struct jpeg_hw_decompress{

    PEGUINT OutputWidth;    /* output image width */
    PEGUINT OutputHeight;    /*output image height */
    PEGUINT OutputColourComp; /*Output color components*/
    PEGLONG OutSize; /*Output Image Size*/
    PEGUBYTE *OutputBuff; /*output data buffer*/
};

#ifdef PEG_JPGHW_WRITE_FRAMEBUFFER
//Defines for display
#define  NTSC   1
#define  PAL    2
/* Function error codes */
#define SUCCESS         0
#define FAILURE         -1

/* Device parameters */
#define OSD_DEVICE      "/dev/fb/0"
#define ATTR_DEVICE     "/dev/fb/2"
#define FBVID_DEVICE    "/dev/fb/3"


#define IPIPE_DEVICE    "/dev/dm355_ipipe"

/* Scaling factors for the video standards */
#define NOSTD           0
#define PALSTD          12
#define NTSCSTD         10

/* The 0-7 transparency value to use for the OSD */
#define OSD_TRANSPARENCY     0x55

#define NUM_DISPLAY_BUFS 1
#define D1_WIDTH        720
#define D1_HEIGHT       yScale(480)
/* Black color in UYVY format */
#define UYVY_BLACK      0x10801080
#define SCREEN_BPP      16

/* Scale vertically depending on video standard */
#define yScale(x) (((x) * gblGetYFactor()) / 10)

#define DEBUG
/* Enables or disables debug output */
#ifdef DEBUG
#define DBG(fmt, args...) fprintf(stderr, "Encodedecode Debug: " fmt, ## args)
#else
#define DBG(fmt, args...)
#endif

#define ERR(fmt, args...) fprintf(stderr, "Encodedecode Error: " fmt, ## args)
#endif //#ifdef PEG_JPGHW_WRITE_FRAMEBUFFER

/* SACALING FACTOR */
#define DM355_NO_SCALE              (256)
#define DM355_UP_SCALE_X_2          (128)
#define DM355_UP_SCALE_X_4          (64)
#define DM355_UP_SCALE_X_8          (32)

#define DM355_DOWN_SCALE_X_2        (512)
#define DM355_DOWN_SCALE_X_4        (1024)
#define DM355_DOWN_SCALE_X_8        (2048)
#define DM355_DOWN_SCALE_X_16       (4096)


#define SLOW_SPEED_RESIZER

/* structure used for IPIPE */
typedef struct
{
    PEGLONG           input_image_width;         /* Input Image width passed to ipipe */
    PEGLONG           input_image_height;        /* Input Image height passed to ipipe */
    PEGLONG           output_image_width;        /* Output Image width expected after rescaling */
    PEGLONG           output_image_height;       /* Output Image height expected after rescaling */
    PEGLONG           input_offset;                 /* Input pointer may be camera pointer */
    PEGLONG           output_offset;                /* Output pointer may be display pointer or ptr passed */
    PEGUBYTE*         ipipe_mapped_input_ptr;    /* ptr returned by mmap() for input buffer of ipipe device */
    PEGUBYTE*         ipipe_mapped_output_ptr;   /* ptr returned by mmap() for output buffer of ipipe device */
    PEGLONG           ipipe_map_in_buf_length;
    PEGLONG           ipipe_map_out_buf_length;
    PEGLONG           num_input_buffers;          /* num of i/p buffers given to ipipe device */
    PEGLONG           num_output_buffers;         /* num of o/p buffers from ipipe device */
    PEGLONG           ipipe_mapped_input_offset;    /* offset returned by mmap() for input buffer of ipipe device */
    PEGLONG           ipipe_mapped_output_offset;    /* offset returned by mmap() for output buffer of ipipe device */
    PEGLONG            buffer_width;                  /*The size of the memory space for each line (in bytes) or pitch */
} device_dm355_ipipe_s;

struct buffer
{
    void *addr;
    int length;
    int offset;
};


/* ipipe structure */
typedef struct
{
    pthread_mutex_t    ipipe_mutex;
    PEGLONG            ipipe_mutex_created;

}device_dm355_ipipe_context_s;

class PegJpgHwConvert
{

    public:

        PegJpgHwConvert();

        virtual ~PegJpgHwConvert();

        virtual PEGBOOL DecodeImage(PegFile *fd, jpeg_hw_decompress *mJpgHwInfo);
       #ifndef PEG_JPGHW_WRITE_FRAMEBUFFER
        virtual void BuildConvertTable();
        virtual PEGBOOL YuvRgbConvert(PEGUBYTE * pYuv_Out,PEGUBYTE *pPut,PEGINT OutputWidth,PEGUINT ScaleEnable);
       #endif

     private:

        String progName;
        String decoderName;
        String engineName;

        PEGUBYTE  *inBuf;
        Engine_Handle ce;
        IMGDEC1_Handle dec;
        IIMGDEC1_Params params;
        device_dm355_ipipe_context_s *g_ipipe_context;

        PEGINT InputSize; //Input Jpeg File size

        PEGINT      DisplayWidth;
        PEGINT      DisplayHeight;
        PEGUSHORT   ImgWidth;
        PEGUSHORT   ImgHeight;
        PEGUSHORT   ActImgWidth;
        PEGUSHORT   ActImgHeight;

        virtual PEGUBYTE GetJpegSize(PEGUBYTE *data, PEGUINT data_size, PEGUSHORT *width, PEGUSHORT *height);

       #ifndef PEG_JPGHW_WRITE_FRAMEBUFFER
         //Parameters required for look up table needed for YUV to RGB conversion
        PEGUBYTE *table;
        PEGINT  * Cr_r_tab;        /* => table for Cr to R conversion */
        PEGINT  * Cb_b_tab;        /* => table for Cb to B conversion */
        PEGLONG * Cr_g_tab;        /* => table for Cr to G conversion */
        PEGLONG * Cb_g_tab;        /* => table for Cb to G conversion */
        PEGUBYTE * sample_range_limit; /* table for fast range-limiting */
       #else //#ifdef PEG_JPGHW_WRITE_FRAMEBUFFER

        PEGINT      displaySize;
        
        PEGINT line_length;
        PEGULONG physDisplays[NUM_DISPLAY_BUFS];
        PEGUBYTE *virtDisplays[NUM_DISPLAY_BUFS];
        PEGINT fd_fb3;
        virtual PEGINT InitDisplayDevice();
        virtual PEGINT DetectVideoStandard(void);
        virtual PEGINT OsdInit();
        virtual PEGINT SetOsdTransparency(unsigned char trans);
        virtual PEGINT CleanupDisplayDevice();

        //For Resizer (IPIPE)
        virtual PEGINT DM355_RESIZE(jpeg_hw_decompress *mJpgHwInfo);
        virtual PEGINT DM355_IPIPE_Open();
        virtual PEGINT DM355_IPIPE_Configure(PEGINT local_ipipe_fd,device_dm355_ipipe_s* p_ipipe_context,jpeg_hw_decompress *mJpgHwInfo);
        virtual PEGINT DM355_IPIPE_Resize_Frame(PEGINT local_ipipe_fd,device_dm355_ipipe_s* p_ipipe_context);
        virtual PEGINT DM355_IPIPE_Close(PEGINT local_ipipe_fd,device_dm355_ipipe_s* p_ipipe_context);

        virtual PEGLONG DM355_Get_Vid1_Fix_Screen_Display_Offset();

        virtual PEGINT DM355_IPIPE_Device_Mutex_Create();
        virtual PEGINT DM355_IPIPE_Lock_Device();
        virtual PEGINT DM355_IPIPE_UnLock_Device();
        virtual PEGINT DM355_IPIPE_Device_Mutex_Delete();

        
       #endif



};

#endif //_PEGJPGHWCONVERT_
#endif //PEG_JPG_HW_CONVERT

